package com.ymatou.iapi.trading.sellerquery.testcase;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.trading.sellerquery.parameter.GetSellerSalesVolumeBean;
import com.ymatou.iapi.trading.sellerquery.parameter.resp.GetSellerSalesVolumeResp;
import com.ymatou.iapi.trading.sellerquery.parameter.vo.SalesVolumeInfo;
import com.ymatou.iapi.trading.sellerquery.service.GetSellerSalesVolumeCall;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymt.utils.tag.P2;
import com.ymttest.database.sqlwapper.DefaultWapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.EnvSetup;
import com.ymttest.utils.YMTDateUtil;
import com.ymttest.utils.constant.ECode;

/**
 * 获取商家成交额成交量接口, 新接口, .net没有这个接口 FreeMaker Template自动生成代码
 */
@SuppressWarnings("rawtypes")
@TestSuite
public class Ts_GetSellerSalesVolume {
	private static GetSellerSalesVolumeBean getsellersalesvolumeBean;
	private static GetSellerSalesVolumeCall getsellersalesvolumeCall;

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("获取商家成交额成交量接口");
	}

	private List<List<Map>> execute(int sellerId, String begin, String end) {
		List<List<Map>> result = new ArrayList<List<Map>>();
		List<Map> unpaid = new DefaultWapper().executeSql(getUnpaidSql(
				sellerId, begin, end));
		List<Map> partialPaid = new DefaultWapper()
				.executeSql(getPartialPaidSql(sellerId, begin, end));
		List<Map> fullPaid = new DefaultWapper().executeSql(getFullPaidSql(
				sellerId, begin, end));
		List<Map> cancelled = new DefaultWapper().executeSql(getCancelledSql(
				sellerId, begin, end));
		List<Map> cancelledUnPaid = new DefaultWapper()
				.executeSql(getCancelledUnPaidSql(sellerId, begin, end));
		result.add(unpaid);
		result.add(partialPaid);
		result.add(fullPaid);
		result.add(cancelled);
		result.add(cancelledUnPaid);
		return result;
	}

	private void verify() {
		GetSellerSalesVolumeResp expectResponse = new GetSellerSalesVolumeResp();
		ConstructExpectedResponse(expectResponse);
		GetSellerSalesVolumeResp actualResponse = getsellersalesvolumeCall
				.getSellerSalesVolumeResp();
		SalesVolumeInfo expUnPaid = expectResponse.getUnPaid();
		SalesVolumeInfo actUnPaid = actualResponse.getUnPaid();
		Logger.comment("开始验证UnPaid");
		verifySalesVolumeInfo("UnPaid", expUnPaid, actUnPaid);
		Logger.comment("结束验证UnPaid");
		SalesVolumeInfo expPartialPaid = expectResponse.getPartialPaid();
		SalesVolumeInfo actPartialPaid = actualResponse.getPartialPaid();
		Logger.comment("开始验证PartialPaid");
		verifySalesVolumeInfo("PartialPaid", expPartialPaid, actPartialPaid);
		Logger.comment("结束验证PartialPaid");
		SalesVolumeInfo expFullPaid = expectResponse.getFullPaid();
		SalesVolumeInfo actFullPaid = actualResponse.getFullPaid();
		Logger.comment("开始验证FullPaid");
		verifySalesVolumeInfo("UnPaid", expFullPaid, actFullPaid);
		Logger.comment("结束验证FullPaid");
		SalesVolumeInfo expCancelled = expectResponse.getCancelled();
		SalesVolumeInfo actCancelled = actualResponse.getCancelled();
		Logger.comment("开始验证Cancelled");
		verifySalesVolumeInfo("UnPaid", expCancelled, actCancelled);
		Logger.comment("结束验证Cancelled");
		SalesVolumeInfo expCancelledUnPaid = expectResponse.getCancelledUnPaid();
		SalesVolumeInfo actCancelledUnPaid = actualResponse.getCancelledUnPaid();
		Logger.comment("开始验证CancelledUnPaid");
		verifySalesVolumeInfo("UnPaid", expCancelledUnPaid, actCancelledUnPaid);
		Logger.comment("结束验证CancelledUnPaid");
	}
	
	private void verifySalesVolumeInfo(String obj,SalesVolumeInfo expect,SalesVolumeInfo actual){
		DataUtil.verify(expect.getLive(), actual.getLive(),"验证"+obj+"对象的live");
		DataUtil.verify(expect.getInStock(), actual.getInStock(),"验证"+obj+"对象的inStock");
		DataUtil.verify(expect.getSales(), actual.getSales(),"验证"+obj+"对象的sales");
		DataUtil.verify(expect.getVolume(), actual.getVolume(),"验证"+obj+"对象的volume");
	}

	private void ConstructExpectedResponse(GetSellerSalesVolumeResp response) {
		List<List<Map>> list = execute(getsellersalesvolumeBean.getSellerId(),
				getsellersalesvolumeBean.getBeginTime(),
				getsellersalesvolumeBean.getEndTime());
		if (false == DataUtil.isNullOrEmpty(list.get(0))) {
			SalesVolumeInfo unPaid = new SalesVolumeInfo();
			DataUtil.mapToBean(unPaid, list.get(0).get(0));
			response.setUnPaid(unPaid);
		} else {
			response.setUnPaid(new SalesVolumeInfo());
		}
		if (false == DataUtil.isNullOrEmpty(list.get(1))) {
			SalesVolumeInfo partialPaid = new SalesVolumeInfo();
			DataUtil.mapToBean(partialPaid, list.get(1).get(0));
			response.setPartialPaid(partialPaid);
		} else {
			response.setPartialPaid(new SalesVolumeInfo());
		}
		if (false == DataUtil.isNullOrEmpty(list.get(2))) {
			SalesVolumeInfo fullPaid = new SalesVolumeInfo();
			DataUtil.mapToBean(fullPaid, list.get(2).get(0));
			response.setFullPaid(fullPaid);
		} else {
			response.setFullPaid(new SalesVolumeInfo());
		}
		if (false == DataUtil.isNullOrEmpty(list.get(3))) {
			SalesVolumeInfo cancelled = new SalesVolumeInfo();
			DataUtil.mapToBean(cancelled, list.get(3).get(0));
			response.setCancelled(cancelled);
		} else {
			response.setCancelled(new SalesVolumeInfo());
		}
		if (false == DataUtil.isNullOrEmpty(list.get(4))) {
			SalesVolumeInfo cancelledUnPaid = new SalesVolumeInfo();
			DataUtil.mapToBean(cancelledUnPaid, list.get(4).get(0));
			response.setCancelledUnPaid(cancelledUnPaid);
		} else {
			response.setCancelledUnPaid(new SalesVolumeInfo());
		}
	}

	private String getUnpaidSql(int sellerId, String begin, String end) {
		String unpaid = "SELECT SUM(IIF(i.iSalesType = 1, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'inStock',"
				+ " SUM(IIF(i.iSalesType = 2 OR i.iSalesType IS NULL, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'live',"
				+ " SUM(i.fProductPrice * i.iAmount + isnull(i.fFreight, 0) + isnull(i.fDiscount, 0)"
				+ " - isnull(i.fSellerPromotionAmount, 0)- isnull(i.fSellerCouponAmount, 0)) AS 'sales',"
				+ " count(DISTINCT o.iOrderId) AS volume"
				+ " FROM Ymt_Orders AS o WITH ( NOLOCK,index = idx_Ymt_Orders_iBuyerId_dAddTime )"
				+ " JOIN Ymt_OrderInfo ( NOLOCK ) AS i ON o.iOrderId = i.iOrderId"
				+ " WHERE o.iBuyerId = "
				+ sellerId
				+ " AND o.dAddTime BETWEEN '"
				+ begin
				+ "' AND '"
				+ end
				+ "' AND o.iTradingStatus = 1;";
		return unpaid;
	}

	private String getPartialPaidSql(int sellerId, String begin, String end) {
		String partialPaid = "SELECT SUM(IIF(i.iSalesType = 1, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'inStock',"
				+ " SUM(IIF(i.iSalesType = 2 OR i.iSalesType IS NULL, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'live',"
				+ " SUM(i.fProductPrice * i.iAmount + isnull(i.fFreight, 0) + isnull(i.fDiscount, 0)"
				+ "  - isnull(i.fSellerPromotionAmount, 0)- isnull(i.fSellerCouponAmount, 0)) AS 'sales',"
				+ " count(DISTINCT o.iOrderId) AS volume"
				+ " FROM dbo.Ymt_Orders AS o WITH ( NOLOCK,index = idx_Ymt_Orders_iBuyerId_dAddTime )"
				+ " JOIN dbo.Ymt_OrderState ( NOLOCK ) AS s ON o.iOrderId = s.iOrderId"
				+ " JOIN Ymt_OrderInfo ( NOLOCK ) AS i ON o.iOrderId = i.iOrderId"
				+ " WHERE o.iBuyerId = "
				+ sellerId
				+ " AND o.dAddTime BETWEEN '"
				+ begin
				+ "' AND '"
				+ end
				+ "' AND s.fPaidAmountOfCash > 0 AND o.fTotalPrice > o.fOrderPrice AND o.bPaidInFull = 0";
		return partialPaid;
	}

	private String getFullPaidSql(int sellerId, String begin, String end) {
		String fullPaid = "SELECT SUM(IIF(i.iSalesType = 1, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'inStock',"
				+ " SUM(IIF(i.iSalesType = 2 OR i.iSalesType IS NULL, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'live',"
				+ " SUM(i.fProductPrice * i.iAmount + isnull(i.fFreight, 0) + isnull(i.fDiscount, 0)"
				+ "  - isnull(i.fSellerPromotionAmount, 0)- isnull(i.fSellerCouponAmount, 0)) AS 'sales',"
				+ " count(DISTINCT o.iOrderId) AS volume"
				+ " FROM dbo.Ymt_Orders AS o WITH ( NOLOCK,index = idx_Ymt_Orders_iBuyerId_dAddTime )"
				+ " JOIN dbo.Ymt_OrderState ( NOLOCK ) AS s ON o.iOrderId = s.iOrderId"
				+ " JOIN Ymt_OrderInfo ( NOLOCK ) AS i ON o.iOrderId = i.iOrderId"
				+ " WHERE o.iBuyerId = "
				+ sellerId
				+ " AND o.dAddTime BETWEEN '"
				+ begin
				+ "' AND '"
				+ end
				+ "' AND s.fPaidAmountOfCash > 0 AND o.bPaidInFull = 1";
		return fullPaid;
	}

	private String getCancelledSql(int sellerId, String begin, String end) {
		String cancelled = "SELECT SUM(IIF(i.iSalesType = 1, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'inStock',"
				+ " SUM(IIF(i.iSalesType = 2 OR i.iSalesType IS NULL, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'live',"
				+ " SUM(i.fProductPrice * i.iAmount + isnull(i.fFreight, 0) + isnull(i.fDiscount, 0)"
				+ "  - isnull(i.fSellerPromotionAmount, 0)- isnull(i.fSellerCouponAmount, 0)) AS 'sales',"
				+ " count(DISTINCT o.iOrderId) AS volume"
				+ " FROM dbo.Ymt_Orders AS o WITH ( NOLOCK,index = idx_Ymt_Orders_iBuyerId_dAddTime )"
				+ " JOIN dbo.Ymt_OrderState ( NOLOCK ) AS s ON o.iOrderId = s.iOrderId"
				+ " JOIN Ymt_OrderInfo ( NOLOCK ) AS i ON o.iOrderId = i.iOrderId"
				+ " WHERE o.iBuyerId = "
				+ sellerId
				+ " AND o.dAddTime BETWEEN '"
				+ begin
				+ "' AND '"
				+ end
				+ "' AND o.iTradingStatus IN (12, 13, 18) AND s.fPaidAmountOfCash > 0";
		return cancelled;
	}

	private String getCancelledUnPaidSql(int sellerId, String begin, String end) {
		String cancelledUnPaid = "SELECT SUM(IIF(i.iSalesType = 1, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'inStock',"
				+ " SUM(IIF(i.iSalesType = 2 OR i.iSalesType IS NULL, i.fProductPrice * i.iAmount + ISNULL(i.fFreight, 0), 0)) AS 'live',"
				+ " SUM(i.fProductPrice * i.iAmount + isnull(i.fFreight, 0) + isnull(i.fDiscount, 0)"
				+ "  - isnull(i.fSellerPromotionAmount, 0)- isnull(i.fSellerCouponAmount, 0)) AS 'sales',"
				+ " count(DISTINCT o.iOrderId) AS volume"
				+ " FROM dbo.Ymt_Orders AS o WITH ( NOLOCK,index = idx_Ymt_Orders_iBuyerId_dAddTime )"
				+ " JOIN dbo.Ymt_OrderState ( NOLOCK ) AS s ON o.iOrderId = s.iOrderId"
				+ " JOIN Ymt_OrderInfo ( NOLOCK ) AS i ON o.iOrderId = i.iOrderId"
				+ " WHERE o.iBuyerId = "
				+ sellerId
				+ " AND o.dAddTime BETWEEN '"
				+ begin
				+ "' AND '"
				+ end
				+ "' AND o.iTradingStatus IN (12, 13, 18) AND s.fPaidAmountOfCash < 0.01";
		return cancelledUnPaid;
	}

	@Before
	public void caseUp() {
		getsellersalesvolumeBean = new GetSellerSalesVolumeBean();
		getsellersalesvolumeCall = new GetSellerSalesVolumeCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(getsellersalesvolumeCall.getOpurl());
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_GetSellerSalesVolume_001() {
		Logger.start(true, "获取商家成交额成交量");
		try {
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));

			getsellersalesvolumeBean.setSellerId(sellerId);
			getsellersalesvolumeBean.setBeginTime(YMTDateUtil
					.getBeforeOrNextDay(-5).replace(" ", "T"));
			getsellersalesvolumeBean.setEndTime(YMTDateUtil.getBeforeOrNextDay(
					2).replace(" ", "T"));
			getsellersalesvolumeCall.setData(getsellersalesvolumeBean);
			getsellersalesvolumeCall.callService();
			Logger.verifyEquals(ECode.SUCCESS,
					getsellersalesvolumeCall.getString("code"), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_GetSellerSalesVolume_002() {
		Logger.start(true, "商家id不存在");
		try {

			getsellersalesvolumeBean.setSellerId(404);
			getsellersalesvolumeBean.setBeginTime(YMTDateUtil
					.getBeforeOrNextDay(-5).replace(" ", "T"));
			getsellersalesvolumeBean.setEndTime(YMTDateUtil.getBeforeOrNextDay(
					2).replace(" ", "T"));
			getsellersalesvolumeCall.setData(getsellersalesvolumeBean);
			getsellersalesvolumeCall.callService();
			Logger.verifyEquals(ECode.SUCCESS,
					getsellersalesvolumeCall.getString("code"), "验证Code");
			verify();
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category({ P1.class })
	@TestCase
	public void Tc_GetSellerSalesVolume_003() {
		Logger.start(true, "商家id为null");
		try {
			getsellersalesvolumeBean.setBeginTime(YMTDateUtil
					.getBeforeOrNextDay(-5).replace(" ", "T"));
			getsellersalesvolumeBean.setEndTime(YMTDateUtil.getBeforeOrNextDay(
					2).replace(" ", "T"));
			getsellersalesvolumeCall.setData(getsellersalesvolumeBean);
			getsellersalesvolumeCall.callService();
			Logger.verifyEquals(ECode.ERROR400,
					getsellersalesvolumeCall.getString("code"), "验证Code");
			Logger.verifyEquals("100",
					getsellersalesvolumeCall.getString("bcode"), "验证Code");
			Logger.verifyEquals("sellerId:must be greater than or equal to 1",
					getsellersalesvolumeCall.getString("msg"), "验证Code");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P2.class })
	@TestCase
	public void Tc_GetSellerSalesVolume_004() {
		Logger.start(true, "BeginTime=null,获取商家成交额成交量失败");
		try {
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			getsellersalesvolumeBean.setSellerId(sellerId);
			getsellersalesvolumeBean.setEndTime(YMTDateUtil.getBeforeOrNextDay(
					2).replace(" ", "T"));
			getsellersalesvolumeCall.setData(getsellersalesvolumeBean);
			getsellersalesvolumeCall.callService();
			DataUtil.verify(ECode.ERROR400, getsellersalesvolumeCall.getCode(), "验证code");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category({ P2.class })
	@TestCase
	public void Tc_GetSellerSalesVolume_005() {
		Logger.start(true, "EndTime=null,获取商家成交额成交量失败");
		try {
			int sellerId = Integer.valueOf(EnvSetup.getData("SellerId"));
			getsellersalesvolumeBean.setSellerId(sellerId);
			getsellersalesvolumeBean.setBeginTime(YMTDateUtil
					.getBeforeOrNextDay(-5).replace(" ", "T"));
			getsellersalesvolumeCall.setData(getsellersalesvolumeBean);
			getsellersalesvolumeCall.callService();
			DataUtil.verify(ECode.ERROR400, getsellersalesvolumeCall.getCode(), "验证code");
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}